use std::sync::Arc;

use actix_web::web::{Data, ServiceConfig};

use crate::{
    mdb::{MClient, MDB},
    Config,
};

use self::{
    article_service::ArticleService, assets_service::AssetsService,
    black_list_service::BlacklistService, club_service::ClubService, email_service::EmailService,
    form_service::FormService, gitee_service::GiteeService, github_service::GithubService,
    invite_service::InviteService, like_list_service::LikeListService,
    message_service::MessageService, profile_service::ProfileService,
    session_service::SessionService, user_service::UserService, wechat_service::WechatService,
};

pub mod article_service;
pub mod assets_service;
pub mod black_list_service;
pub mod club_service;
pub mod email_service;
pub mod form_service;
pub mod gitee_service;
pub mod github_service;
pub mod invite_service;
pub mod like_list_service;
pub mod message_service;
pub mod profile_service;
pub mod session_service;
pub mod user_service;
pub mod wechat_service;

pub fn configure_services(
    mdb: MDB,
    m_client: MClient,
    config: Arc<Config>,
    cdb: sled::Db,
) -> impl FnOnce(&mut ServiceConfig) {
    move |cfg: &mut ServiceConfig| {
        // 构造服务
        let email_service = Arc::new(EmailService::new(config.clone(), mdb.clone()));
        let user_service = Arc::new(UserService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
            cdb,
            email_service.clone(),
        ));
        let black_list_service = Arc::new(BlacklistService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let article_service = Arc::new(ArticleService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        // session中间件必须要session服务
        let session_service = Arc::new(SessionService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let like_list_service = Arc::new(LikeListService::new(
            mdb.clone(),
            m_client.clone(),
            config.clone(),
        ));
        let club_service = Arc::new(ClubService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
            user_service.clone(),
            like_list_service.clone(),
        ));
        let assets_service = Arc::new(AssetsService::new(
            config.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let form_service = Arc::new(FormService::new(
            club_service.clone(),
            user_service.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let message_service = Arc::new(MessageService::new(
            config.clone(),
            club_service.clone(),
            user_service.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let invite_service = Arc::new(InviteService::new(
            config.clone(),
            club_service.clone(),
            user_service.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let wechat_service = Arc::new(WechatService::new(
            config.clone(),
            user_service.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let github_service = Arc::new(GithubService::new(
            config.clone(),
            user_service.clone(),
            mdb.clone(),
            m_client.clone(),
        ));
        let gitee_service = Arc::new(GiteeService::new(
            config,
            user_service.clone(),
            mdb.clone(),
            m_client,
        ));
        let profile_service = Arc::new(ProfileService::new(mdb));
        cfg.app_data(Data::from(user_service))
            .app_data(Data::from(club_service))
            .app_data(Data::from(assets_service))
            .app_data(Data::from(form_service))
            .app_data(Data::from(message_service))
            .app_data(Data::from(invite_service))
            .app_data(Data::from(wechat_service))
            .app_data(Data::from(github_service))
            .app_data(Data::from(gitee_service))
            .app_data(Data::from(like_list_service))
            .app_data(Data::from(session_service))
            .app_data(Data::from(article_service))
            .app_data(Data::from(black_list_service))
            .app_data(Data::from(email_service))
            .app_data(Data::from(profile_service));
    }
}
